package br.urca.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import br.com.caelum.vraptor.Controller;
import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.jasperreports.Report;
import br.com.caelum.vraptor.jasperreports.download.ReportDownload;
import br.com.caelum.vraptor.jasperreports.formats.ExportFormats;
import br.com.caelum.vraptor.jasperreports.formats.Pdf;
import br.com.caelum.vraptor.observer.download.Download;
import br.urca.dao.AlunosCursoDAO;
import br.urca.dao.DisciplinaDAO;
import br.urca.dao.DisciplinasCursadasDAO;
import br.urca.dao.DisciplinasMatriculadasDAO;
import br.urca.dao.OfertaDAO;
import br.urca.interceptor.InterceptResource;
import br.urca.model.AlunoCurso;
import br.urca.model.Disciplina;
import br.urca.model.DisciplinaCursada;
import br.urca.model.DisciplinaMatriculada;
import br.urca.model.Oferta;
import br.urca.model.json.AlunoNota;
import br.urca.model.json.AlunoNotaPOST;
import br.urca.model.json.DisciplinaComOferta;
import br.urca.report.DisciplinaReport;

@Controller
@InterceptResource
public class LancamentoNotasController {
	
	public static final int LENGTH_OFERTA = 5;
	public static final int LENGTH_PEDIDO = 5;

	private AlunosCursoDAO mAlunoCursoDAO;
	private DisciplinasMatriculadasDAO mMatriculadasDAO;
	private DisciplinasCursadasDAO mCursadasDAO;
	private DisciplinaDAO mDisciplinaDAO;
	private OfertaDAO mOfertaDAO;
	private Result result;
	HttpServletRequest request;
	
	ServletContext context;
	
	/*@Resource(name = "default", lookup = "java:jboss/datasources/UrcaDS")
	private DataSource ds;*/
	
	private List<AlunoNota> listaAlunos = new ArrayList<AlunoNota>();

	public LancamentoNotasController() { }

	@Inject
	public LancamentoNotasController(AlunosCursoDAO mAlunoCursoDAO, DisciplinasCursadasDAO mCursadasDAO,
			DisciplinasMatriculadasDAO mMatriculadasDAO, HttpServletRequest request, ServletContext context,
			DisciplinaDAO mDisciplinaDAO, OfertaDAO mOfertaDAO, Result result) {
		super();
		this.mAlunoCursoDAO = mAlunoCursoDAO;
		this.mCursadasDAO = mCursadasDAO;
		this.mMatriculadasDAO = mMatriculadasDAO;
		this.mDisciplinaDAO = mDisciplinaDAO;
		this.mOfertaDAO = mOfertaDAO;
		this.result = result;
		this.request = request;
		this.context = context;
	}

	@Get("/lancamentonotas")	
	public void index() {
		request.getSession().removeAttribute("oferta");
		request.getSession().removeAttribute("pedido");
		request.getSession().removeAttribute("atualizar_cursadas");
	}
	
	@Get("/lancamentonotas/alunos")
	public void lista() { 
		
	}
	
	@Path("/lancamentonotas/pdf")
	public Download pdfReport() {
		
		List<Disciplina> mList= mDisciplinaDAO.todos();
			if (mList != null) {
	        Report report = new DisciplinaReport(mList);
	        String realPath = context.getRealPath("/WEB-INF/reports/images/");
	        report.addParameter("realPath", realPath);
	        return new ReportDownload(report, ExportFormats.pdf(), false);
		} else {
			return null;
		}
    } 
	
	public void buscarDisciplinaPorNome(String nome, String oferta) {
		if (nome != null) {
			Properties properties = new Properties();
			
			if (nome != null) {
				List<Disciplina> mList = mDisciplinaDAO.buscarPorNome(nome);
				if ((mList != null) && (!mList.isEmpty())) {
					
					List<Oferta> mListOfertas = new ArrayList<Oferta>();
					List<DisciplinaComOferta> mListDisciplinaComOfertas = 
							new ArrayList<DisciplinaComOferta>();
					mListOfertas.clear();
					
					for(Disciplina d: mList) {
						mListOfertas.addAll(
								mOfertaDAO.buscarPorOfertaDisciplina(oferta, d.getCodDisciplina()));
						for(Oferta o: mListOfertas) {
							mListDisciplinaComOfertas.add(new DisciplinaComOferta(o, d.getNomeDisciplina()));
						}
						mListOfertas.clear();
					}
					
					result.include("listaOferta", mListDisciplinaComOfertas);
					result.redirectTo(this).index();
				} else {
					result.include("listaOferta", new ArrayList<>());
				}
			}
			
		}
	}

	public void buscar(Oferta oferta) {

		if ((oferta != null) && 
				(oferta.getId().getCodOferta() != null) && 
				(oferta.getId().getCodPedido()!= null)) {
			
			//Valida dados informados pelo usuário
			try {
				Integer.parseInt(oferta.getId().getCodOferta());
				Integer.parseInt(oferta.getId().getCodPedido());
				if ((oferta.getId().getCodOferta().length() < LENGTH_OFERTA)
						|| (oferta.getId().getCodPedido().length() < LENGTH_PEDIDO)) {
					throw new Exception();
				}
			} catch(Exception e) {
				result.include("mensagem", "Oferta e/ou pedido inválido. "
						+ "Por favor verifique e tente novamente!");
				result.redirectTo(this).index();
				return;
			}
			
				
			Oferta mOferta = mOfertaDAO.buscarPorOfertaPedido(oferta.getId()
					.getCodOferta(), oferta.getId().getCodPedido());

			List<DisciplinaMatriculada> mListDisciplinas = mMatriculadasDAO
					.buscarPorOferta(mOferta);

			AlunoCurso alunoCurso;
			Disciplina disciplina = null;
			AlunoNota alunoNota;
			
			if (!mListDisciplinas.isEmpty()) { 
				
				request.getSession().setAttribute("atualizar_cursadas", false);
				
				for (DisciplinaMatriculada dm : mListDisciplinas) {
	
					alunoCurso = mAlunoCursoDAO.buscaPorMatricula(dm.getId()
							.getMatricula());
	
					disciplina = mDisciplinaDAO.buscarPorId(mOferta
							.getCodDisciplina());
					try {
						alunoNota = new AlunoNota(alunoCurso.getAluno().getNome(),
								alunoCurso.getMatricula(), 
								(dm.getNotaAV1() != null ? 
										String.valueOf(dm.getNotaAV1()).toString().replace(".", ",") : ""),
								(dm.getNotaAV2() != null ? 
										String.valueOf(dm.getNotaAV2()).toString().replace(".", ",") : ""), 
								(dm.getNotaAVF() != null ? 
										String.valueOf(dm.getNotaAVF()).toString().replace(".", ",") : ""),
								(dm.getMedia() != null ?		
										String.valueOf(dm.getMedia()).toString().replace(".", ",") : ""),
								disciplina.getNomeDisciplina());
						this.listaAlunos.add(alunoNota);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			} else {
				
				request.getSession().setAttribute("atualizar_cursadas", true);
				
				List<DisciplinaCursada> mList = mCursadasDAO
						.buscarPorOferta(mOferta);
				
				for (DisciplinaCursada dm : mList) {

					alunoCurso = mAlunoCursoDAO.buscaPorMatricula(dm.getId()
							.getMatricula());

					disciplina = mDisciplinaDAO.buscarPorId(mOferta
							.getCodDisciplina());
					try {
						alunoNota = new AlunoNota(alunoCurso.getAluno().getNome(),
								alunoCurso.getMatricula(), 
								(dm.getNotaAV1() != null ? 
										String.valueOf(dm.getNotaAV1()).toString().replace(".", ",") : ""),
								(dm.getNotaAV2() != null ? 
										String.valueOf(dm.getNotaAV2()).toString().replace(".", ",") : ""), 
								(dm.getNotaAVF() != null ? 
										String.valueOf(dm.getNotaAVF()).toString().replace(".", ",") : ""),
								(dm.getMedia() != null ?		
										String.valueOf(dm.getMedia()).toString().replace(".", ",") : ""),
								disciplina.getNomeDisciplina());
						this.listaAlunos.add(alunoNota);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
			if (!this.listaAlunos.isEmpty()) {
				Collections.sort(listaAlunos, AlunoNota.POR_NOME);
				result.include("listaAlunos", listaAlunos);
				request.getSession().setAttribute("oferta", mOferta.getId().getCodOferta());
				request.getSession().setAttribute("pedido", mOferta.getId().getCodPedido());
				if (disciplina != null)
					result.include("nomeDisciplina", disciplina.getNomeDisciplina());
				else
					result.include("nomeDisciplina", "");
				result.redirectTo(this).lista();
			}
			
			result.include("mensagem", "Nada retornado pelo servidor!");
			
		} else {
			result.include("mensagem", "Nada retornado pelo servidor!"
					+ "\nPor favor verifique se o nº de oferta e pedido estão corretos!");
			result.redirectTo(this).index();
		}
	}//fim do método buscar
	
	public void salvarNotas(List<AlunoNota> listaAlunos) {
		
		if (!listaAlunos.isEmpty()) {
			boolean atualizarCursadas = (boolean) request.getSession().getAttribute("atualizar_cursadas");
			String oferta = (String) request.getSession().getAttribute("oferta");
			String pedido = (String) request.getSession().getAttribute("pedido"); 
			List<AlunoNotaPOST> mListNotas = new ArrayList<AlunoNotaPOST>();
			if ((oferta != null) && (pedido != null)) {
				for (AlunoNota aluno: listaAlunos) {
					if (aluno.getMatricula() != null) {
						double av1 = 0;
						double av2 = 0;
						
						if (aluno.getNotaAV1() != null) {
							av1 = Double.parseDouble(aluno.getNotaAV1().replace(",", "."));						
						}
						
						if (aluno.getNotaAV2() != null) {
							av2 = Double.parseDouble(aluno.getNotaAV2().replace(",", "."));	
						}
						
						mListNotas.add(new AlunoNotaPOST(oferta, pedido, aluno.getMatricula(), 
								(av1 != 0 ? av1 : null), (av2 != 0 ? av2 : null)));
					}
				}
				
				try {
					for (AlunoNotaPOST mAlunoNotaPOST: mListNotas) {
						if (!atualizarCursadas) {
							DisciplinaMatriculada dm = mMatriculadasDAO
									.buscarPorOfertaPedidoMatricula(mAlunoNotaPOST.getOferta(), 
											mAlunoNotaPOST.getPedido(), mAlunoNotaPOST.getMatricula());
							if (dm != null) {					
								dm.setNotaAV1(mAlunoNotaPOST.getNotaAv1());
								dm.setNotaAV2(mAlunoNotaPOST.getNotaAv2());
								mMatriculadasDAO.atualizar(dm);
								
							}
						} else {
							DisciplinaCursada dm = mCursadasDAO
									.buscarPorOfertaPedidoMatricula(mAlunoNotaPOST.getOferta(), 
											mAlunoNotaPOST.getPedido(), mAlunoNotaPOST.getMatricula());
							if (dm != null) {					
								dm.setNotaAV1(mAlunoNotaPOST.getNotaAv1());
								dm.setNotaAV2(mAlunoNotaPOST.getNotaAv2());
								mCursadasDAO.atualizar(dm);
								
							}
						}
					}	
					result.include("mensagem","Notas gravadas com sucesso!").redirectTo(this).index();
					request.getSession().removeAttribute("oferta");
					request.getSession().removeAttribute("pedido");
					request.getSession().removeAttribute("atualizar_cursadas");
				} catch(Exception e) {
					result.include("mensagem","Falha ao salvar notas! "+e.getMessage());
				}
			}
		}
	}

}
